//
//  _HACTecNodeKDJ.m
//  HStockCharts
//
//  Created by Hotacool on 2018/10/3.
//

#import "_HACTecNodeKDJ.h"
#import "HACLineChartDataSet.h"
#import "HACPointEntry.h"
#import "HACGradientWave.h"
#import "HACTecCalculator.h"

@interface _HACTecNodeKDJ ()
/** k线数据 */
@property (nonatomic, copy) NSArray *kLineData;
@property (nonatomic, copy) NSArray<HACTecKDJEntry*> *KDJData;
/** 点数据 */
@property (nonatomic, strong) NSMutableDictionary <NSNumber*, NSArray<HACPointEntry*>*> *lineDicData;
/** 画线点数据 */
@property (nonatomic, strong) NSMutableArray *lineDrawingData;
/** 画笔 */
@property (nonatomic, strong) HACGradientWave *lineBrush;

@property (nonatomic, assign) BOOL isCenter;// 画线点居中,点位于1/2singlewidth
@end
@implementation _HACTecNodeKDJ
- (void)setUp {
    [super setUp];
    self.xAxisCount = 3;
    self.yAxisCount = 5;
    self.N = 9;
    self.M1 = 3;
    self.M2 = 3;
    self.pointRect = CGRectZero;
    self.singleWidth = 1.0;
    self.isCenter = YES;// kline
    _lineBrush = [[HACGradientWave alloc] initWithDataProvider:self];
}

- (void)removeNode {
    [super removeNode];
    [self.lineBrush removeBrush];
}

- (void)setData:(HACChartData *)data {
    _kLineData = [data dataSetWithLabel:HACKLineViewDataLabel].values;
    if (!_kLineData) {//分时数据
        _kLineData = [data dataSetWithLabel:HACTimeLineViewDataLabel].values;
    }
    _KDJData = [HACTecCalculator calculateKDJWithData:_kLineData N:self.N M1:self.M1 M2:self.M2];
    // macd line
    _lineDicData = [NSMutableDictionary dictionary];
    _lineDrawingData = [NSMutableArray array];
    NSMutableArray *point_k = [NSMutableArray arrayWithCapacity:_KDJData.count];
    NSMutableArray *point_d = [NSMutableArray arrayWithCapacity:_KDJData.count];
    NSMutableArray *point_j = [NSMutableArray arrayWithCapacity:_KDJData.count];
    [_KDJData enumerateObjectsUsingBlock:^(HACTecKDJEntry * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [point_k addObject:[[HACPointEntry alloc] initWithX:idx y:self.KDJData[idx].K]];
        [point_d addObject:[[HACPointEntry alloc] initWithX:idx y:self.KDJData[idx].D]];
        [point_j addObject:[[HACPointEntry alloc] initWithX:idx y:self.KDJData[idx].J]];
    }];
    HACLineComponents *lineItem = [[HACLineComponents alloc] init];
//    lineItem.isCurve = YES;
    lineItem.lineColor = RGB_HEX(kDarkBlueColor);
    lineItem.fillColor = nil;
    lineItem.isGradient = YES;
    lineItem.index = 0;
    lineItem.lineBolder = 1;
    [_lineDrawingData addObject:lineItem];
    [_lineDicData setObject:point_k forKey:@(0)];
    lineItem = [[HACLineComponents alloc] init];
//    lineItem.isCurve = YES;
    lineItem.lineColor = RGB_HEX(kDarkPinkColor);
    lineItem.fillColor = nil;
    lineItem.isGradient = YES;
    lineItem.index = 1;
    lineItem.lineBolder = 1;
    [_lineDrawingData addObject:lineItem];
    [_lineDicData setObject:point_d forKey:@(1)];
    lineItem = [[HACLineComponents alloc] init];
//    lineItem.isCurve = YES;
    lineItem.lineColor = RGB_HEX(kRedColor);
    lineItem.fillColor = nil;
    lineItem.isGradient = YES;
    lineItem.index = 1;
    lineItem.lineBolder = 1;
    [_lineDrawingData addObject:lineItem];
    [_lineDicData setObject:point_j forKey:@(2)];
    
    self.startIndex = MAX(0, self.actualCount - self.visualCount);
    self.endIndex = MAX(self.visualCount, self.actualCount - 1);
    
    [super setData:data];
}

- (CGFloat)maxContentWidth {
    return MAX(self.actualCount * self.singleWidth , [super maxContentWidth]);
}

- (void)updateFrame {
    self.pointRect = self.relativeFrame;
    self.singleWidth = FormatValueWithRemain(self.relativeFrame.size.width / (self.visualCount), 3);// 可见数即visualCount
}

- (void)setNeedsDisplay {
    [super setNeedsDisplay];
    if (self.hostLayer) {
        [self.lineBrush drawInLayer:self.hostLayer inRect:self.relativeFrame];
    }
}

- (NSInteger)actualCount {
    return _KDJData?_KDJData.count:0;
}

#pragma mark - provider protocol
- (NSArray <HACAxisComponents *>*)xAxisDatasInRect:(CGRect)rect {
    NSInteger axisCount = self.xAxisCount;
    if (axisCount <= 0)
        return nil;
    
    NSMutableArray *xAxisDrawingData = [NSMutableArray array];
    // 从下往上
    for (int index = 0; index < axisCount; index++) {
        HACAxisComponents *axisItem = [[HACAxisComponents alloc] init];
        axisItem.index = index;
        axisItem.lineBolder = 0.5;
        axisItem.axisType = DrawingAxisTypeX;
        axisItem.queueLocation = CGQueueLocation(index, axisCount);
        CGFloat y = [self calculatorYForValue:index min:0 max:axisCount - 1 inRect:self.relativeFrame];
        [xAxisDrawingData addObject:axisItem];
        
        // x轴左边的默认值，按照最大值等分
        axisItem.text = [self stringForAxisTextItem:axisItem];
        if (!axisItem.text) {
            CGFloat yValue = self.minValue + (ABS(self.maxValue - self.minValue) / (axisCount - 1)) * index;
            long digits = self.basicInfoData.priceDigits!=0?self.basicInfoData.priceDigits:0;
            axisItem.text = [NSString stringWithFormat:@"%.2f", yValue/pow(10, digits)];
            axisItem.textFont = self.leftAxis.textFont;
        }
        
        CGSize textSize = [axisItem.text sizeWithAttributes:@{NSFontAttributeName : axisItem.textFont}];
        CGRect frame = CGRectMake(CGRectGetMinX(rect)+7, y, textSize.width , textSize.height);
        if (axisItem.queueLocation == QueueLocationHead) {
            // 最下面一个下坐标对其线的位置
            frame.origin.y -= textSize.height;
        } else if (axisItem.queueLocation == QueueLocationTrail) {
            // 最上面一个上坐标对其线的位置
        } else {
            frame.origin.y -= textSize.height / 2; // 中间的跟线居中对齐
            axisItem.text = @"";
            axisItem.extText = @"";
            if (index == axisCount/2) {
                axisItem.dashLengths = @[@2.0, @4.0];//中间线为开盘价，虚线
                axisItem.lineBolder = 1;
            }
        }
        axisItem.textFrame = frame;
        axisItem.extText = nil;
        axisItem.extTextFrame = CGRectZero;
        CGLine line;
        line = CGLineMake(self.relativeFrame.origin.x, y, CGRectGetMaxX(self.relativeFrame), y);
        axisItem.line = line;
        axisItem.lineColor = self.leftAxis.lineColor?:axisItem.lineColor;
    }
    return xAxisDrawingData;
}
- (NSArray *)lineDatasInRect:(CGRect)rect {
    if (!self.data)
        return nil;
    
    int index = 0;
    for (HACLineComponents *lineItem in self.lineDrawingData) {
        NSArray *points = _lineDicData[@(index)];
        if (!points) {
            continue;
        }
        lineItem.pointCount = (self.endIndex - self.startIndex) + 1;
        NSMutableArray *pointsArray = [NSMutableArray array];
        
        for (NSInteger i = self.startIndex; i <= self.endIndex && i < self.actualCount; i++) {
            if (i >= points.count) {
                break;
            }
            id pointData = points[i];
            CGFloat x = 0.0, y = 0.0;
            NSInteger idx = [self relativeIdxFromIndex:i];
            x = [self xPointForIndex:idx inRect:self.pointRect];
            if (self.isCenter) {//偏移1/2singleWidth,点居中
                x += self.singleWidth / 2;
            }
            CGFloat value = [self lineValueForItem:pointData lineIndex:lineItem.index];
            if (value <= 0) {//0值不显示
                [pointsArray addObject:NSStringFromCGPoint(CGPointMake(x, kDrawingInvaildValue))];
            } else {
                y = [self calculatorYForValue:value min:self.minValue max:self.maxValue inRect:self.pointRect];
                [pointsArray addObject:NSStringFromCGPoint(CGPointMake(x, y))];
            }
        }
        lineItem.pointArray = pointsArray;
        index++;
    }
    return self.lineDrawingData;
}

- (CGFloat)lineValueForItem:(HACPointEntry *)data lineIndex:(NSInteger)index {
    return data.y;
}

// 计算最大，最小值
- (void)calculateLimitValue {
    CGFloat __block max = FLT_MIN;
    CGFloat __block min = FLT_MAX;
    
    long start = self.startIndex;
    long len = self.endIndex - self.startIndex + 1;
    if (start+len>self.actualCount) {
        len = self.actualCount - start;
    }
    if (len < 0) {
        len = 0;
    }
    if (self.KDJData && start + len <= self.KDJData.count) {
        [[self.KDJData subarrayWithRange:NSMakeRange(start, len)] enumerateObjectsUsingBlock:^(HACTecKDJEntry * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            CGFloat tempMax = MAX(MAX(obj.K, obj.D), obj.J);
            if (tempMax > max) {
                max = tempMax;
            }
            CGFloat tempMin = MIN(MIN(obj.K, obj.D), obj.J);
            if (tempMin < min && tempMin > 0) {//排除0值
                min = tempMin;
            }
        }];
    }
    
    self.maxValue = (max == FLT_MIN) ? .0 : max;
    self.minValue = (min == FLT_MAX) ? .0 : min;
}

- (HACChartDataEntry*)dataAtChartForIndex:(NSUInteger)focusIndex {
    HACChartDataEntry *indexData = [super dataAtChartForIndex:focusIndex];
    if (self.KDJData && focusIndex < self.kLineData.count) {
        indexData = self.KDJData[focusIndex];
    }
    return indexData;
}
@end
